package stack.era.presentation.char_side_screen;

import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.util.HashMap;

import javax.swing.JLabel;

import stack.era.constants.CharacterAttributes;
import stack.era.constants.CharacterAttributes.Skill;
import stack.era.constants.CharacterAttributes.Stat;
import stack.era.constants.FrameAttributes.SideScreen;
import stack.era.domain.DomainHome;
import stack.era.presentation.ERAInfoPanel;
import stack.era.presentation.side_screen.ERASideScreen;

public class PlayerCharacterSideScreen extends ERASideScreen {

	private static final long serialVersionUID = -8897563015624389505L;

	private HashMap<Stat, JLabel> statLabels;
	private HashMap<Skill, JLabel> skillLabels;
	private HashMap<Stat, ERAPlusButton> statIncreaseButtons;
	private HashMap<Skill, ERAPlusButton> skillIncreaseButtons;
	private JLabel name, level, availableStatPoints, availableSkillPoints;

	/**
	 * Setup the character display panel.
	 * 
	 */
	public PlayerCharacterSideScreen() {
		super(SideScreen.CHARACTER);

		// Initialize labels
		statLabels = new HashMap<Stat, JLabel>();
		for (Stat s : Stat.values()) {
			JLabel l = new JLabel();
			l.setHorizontalAlignment(JLabel.CENTER);
			statLabels.put(s, l);
		}

		skillLabels = new HashMap<Skill, JLabel>();
		for (Skill s : Skill.values()) {
			JLabel l = new JLabel();
			l.setHorizontalAlignment(JLabel.CENTER);
			skillLabels.put(s, l);
		}

		name = new JLabel();
		level = new JLabel();

		// Initialize buttons
		skillIncreaseButtons = new HashMap<Skill, ERAPlusButton>();
		statIncreaseButtons = new HashMap<Stat, ERAPlusButton>();

		// Setup panel layout
		ERAInfoPanel basicInfo = new ERAInfoPanel();
		basicInfo.setLayout(new GridLayout(2, 1));
		name.setHorizontalAlignment(JLabel.CENTER);
		basicInfo.add(name);
		level.setHorizontalAlignment(JLabel.CENTER);
		basicInfo.add(level);

		ERAInfoPanel stats = new ERAInfoPanel();
		stats.setLayout(new GridLayout(Stat.values().length + 2, 3));
		stats.add(new JLabel());
		stats.add(new JLabel());
		availableStatPoints = new JLabel();
		availableStatPoints.setHorizontalAlignment(JLabel.CENTER);
		availableStatPoints.setForeground(new Color(0, 100, 0));
		stats.add(availableStatPoints);
		for (Stat s : Stat.values()) {
			JLabel statLabel = new JLabel("  " + s.getFullName());
			statLabel.setHorizontalAlignment(JLabel.RIGHT);
			stats.add(statLabel);
			stats.add(statLabels.get(s));
			statIncreaseButtons.put(s, new ERAPlusButton());
			statIncreaseButtons.get(s).addActionListener(
					new StatIncreaseControl(s));
			stats.add(statIncreaseButtons.get(s));
		}
		stats.add(new JLabel());
		stats.add(new JLabel());
		stats.add(new JLabel());

		ERAInfoPanel skills = new ERAInfoPanel();
		skills.setLayout(new GridLayout(Skill.values().length + 2, 3));
		skills.add(new JLabel());
		skills.add(new JLabel());
		availableSkillPoints = new JLabel();
		availableSkillPoints.setHorizontalAlignment(JLabel.CENTER);
		availableSkillPoints.setForeground(new Color(0, 100, 0));
		skills.add(availableSkillPoints);
		for (Skill s : Skill.values()) {
			JLabel skillLabel = new JLabel("  " + s.getFullName());
			skillLabel.setHorizontalAlignment(JLabel.RIGHT);
			skills.add(skillLabel);
			skills.add(skillLabels.get(s));
			skillIncreaseButtons.put(s, new ERAPlusButton());
			skillIncreaseButtons.get(s).addActionListener(
					new SkillIncreaseControl(s));
			skills.add(skillIncreaseButtons.get(s));
		}
		skills.add(new JLabel());
		skills.add(new JLabel());
		skills.add(new JLabel());

		this.setLayout(new GridBagLayout());
		GridBagConstraints c = new GridBagConstraints();
		c.insets = new Insets(5, 5, 5, 5);
		c.anchor = GridBagConstraints.FIRST_LINE_START;
		c.ipady = 30;
		c.ipadx = 60;
		c.gridx = 0;

		c.gridy = 0;
		this.add(basicInfo, c);
		c.gridy = 1;
		this.add(stats, c);
		c.gridy = 2;
		this.add(skills, c);
	}

	@Override
	public void populate() {
		DomainHome domain = DomainHome.getInstance();
		String playerName = domain.getWorld().getPlayerCharacterName();

		if (playerName != null) {
			int statPoints = domain.getPlayerCharacter().getStatPoints();
			if (statPoints > 0) {
				availableStatPoints.setVisible(true);
				availableStatPoints.setText(statPoints + " Available");
			} else {
				availableStatPoints.setVisible(false);
			}
			int skillPoints = domain.getPlayerCharacter().getSkillPoints();
			if (skillPoints > 0) {
				availableSkillPoints.setVisible(true);
				availableSkillPoints.setText(skillPoints + " Available");
			} else {
				availableSkillPoints.setVisible(false);
			}

			for (Stat s : Stat.values()) {
				statLabels.get(s).setText(
						String.valueOf(domain.getPlayerCharacter().getStat(s)));
			}

			for (Skill s : Skill.values()) {
				skillLabels.get(s)
						.setText(
								String.valueOf(domain.getPlayerCharacter()
										.getSkill(s)));
			}

			name.setText(domain.getPlayerCharacter().getName());
			level.setText("Level "
					+ String.valueOf(domain.getPlayerCharacter().getLevel()));

			this.syncButtons(domain, playerName, statPoints, skillPoints);
		}
	}

	private void syncButtons(DomainHome domain, String playerName,
			int statPoints, int skillPoints) {

		String status = null;
		int value = 0;

		for (Stat s : Stat.values()) {
			status = ERAPlusButton.ACTIVE_STATUS;
			value = domain.getPlayerCharacter().getStat(s);
			// Check for active status
			if (value < CharacterAttributes.MAX_STAT_POINTS) {
				this.statIncreaseButtons.get(s).setEnabled(true);
				status = ERAPlusButton.ACTIVE_STATUS;
			}
			// Check for no points status
			if (statPoints <= 0) {
				this.statIncreaseButtons.get(s).setEnabled(false);
				status = ERAPlusButton.NO_POINTS_STATUS;
			}
			// Check for maxed status
			if (value >= CharacterAttributes.MAX_STAT_POINTS) {
				this.statIncreaseButtons.get(s).setEnabled(false);
				status = ERAPlusButton.MAXED_STATUS;
			}
			this.statIncreaseButtons.get(s).setStatus(status);
		}

		for (Skill s : Skill.values()) {
			status = ERAPlusButton.ACTIVE_STATUS;
			value = domain.getPlayerCharacter().getSkill(s);
			// Check for active status\
			if (value < CharacterAttributes.MAX_SKILL_POINTS) {
				this.skillIncreaseButtons.get(s).setEnabled(true);
				status = ERAPlusButton.ACTIVE_STATUS;
			}
			// Check for no points status
			if (skillPoints <= 0) {
				this.skillIncreaseButtons.get(s).setEnabled(false);
				status = ERAPlusButton.NO_POINTS_STATUS;
			}
			// Check for maxed status
			if (value >= CharacterAttributes.MAX_SKILL_POINTS) {
				this.skillIncreaseButtons.get(s).setEnabled(false);
				status = ERAPlusButton.MAXED_STATUS;
			}
			this.skillIncreaseButtons.get(s).setStatus(status);
		}
	}
}
